package io.noties.markwon.app.readme;


import com.noties.markwon.utils.LogUtils;
import com.noties.markwon.wrapper.view.RecyclerView;

import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.MarkwonVisitor;
import io.noties.markwon.app.ResourceTable;
import io.noties.markwon.app.utils.ReadMeUtils;
import io.noties.markwon.app.utils.SampleUtilsKt;
import io.noties.markwon.app.utils.TextViewUtils;
import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.ImagesPlugin;
import io.noties.markwon.recycler.MarkwonAdapter;
import io.noties.markwon.recycler.SimpleEntry;
import io.noties.markwon.recycler.table.TableEntry;
import io.noties.markwon.recycler.table.TableEntryPlugin;
import io.noties.prism4j.annotations.PrismBundle;
import java.io.IOException;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.app.Context;
import ohos.utils.PacMap;
import ohos.utils.Pair;
import ohos.utils.net.Uri;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import org.commonmark.ext.gfm.tables.TableBlock;
import org.commonmark.node.FencedCodeBlock;
import org.commonmark.node.Node;

@PrismBundle(includeAll = true)
public class ReadMeActivity extends Ability {

    private Component progressBar;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        setUIContent(ResourceTable.Layout_activity_read_me);

        progressBar = findComponentById(ResourceTable.Id_progress_bar);

        Uri data = intent.getUri();

        initAppBar(data);
        // initRecyclerView(data);
    }

    private final Markwon markwon = Markwon.builder(this)
            .usePlugin(ImagesPlugin.create())
            .usePlugin(HtmlPlugin.create())
            .usePlugin(TableEntryPlugin.create(this))
            // .usePlugin(SyntaxHighlightPlugin.create(new Prism4j(new GrammarLocatorDef()), Prism4jThemeDefault.create(0)))
            .usePlugin(TaskListPlugin.create(this))
            // .usePlugin(StrikethroughPlugin.create())
            // .usePlugin(new ReadMeImageDestinationPlugin(getIntent().getUri()))

            .usePlugin(new AbstractMarkwonPlugin() {
                @Override
                public void configureConfiguration(MarkwonConfiguration.Builder builder) {
                    super.configureConfiguration(builder);
                    builder.linkResolver(new ReadMeLinkResolver());
                }

                @Override
                public void configureVisitor(MarkwonVisitor.Builder builder) {
                    super.configureVisitor(builder);
                    builder.on(FencedCodeBlock.class, (visitor, block) -> {
                        CharSequence code = visitor.configuration()
                                .syntaxHighlight()
                                .highlight(block.getInfo(), block.getLiteral().trim());
                        visitor.builder().append(code);
                    });
                }
            }).build();


    private void initAppBar(Uri data) {
        DirectionalLayout appBar = (DirectionalLayout) findComponentById(ResourceTable.Id_app_bar);
        appBar.findComponentById(ResourceTable.Id_app_bar_icon).setClickedListener(component -> onBackPressed());

        Pair<String, String> mPair;
        if (data == null) {
            mPair = new Pair<>("README.md", null);
        } else {
            mPair = new Pair<>(data.getLastPath(), data.toString());
        }
        ((Text) appBar.findComponentById(ResourceTable.Id_title)).setText(mPair.f);
        TextViewUtils.textOrHide((Text) appBar.findComponentById(ResourceTable.Id_subtitle), mPair.s);

    }

    private void initRecyclerView(Uri data) {

        MarkwonAdapter adapter = MarkwonAdapter.builder(ResourceTable.Layout_adapter_node, ResourceTable.Id_text_view)
                .include(FencedCodeBlock.class, SimpleEntry
                    .create(ResourceTable.Layout_adapter_node_code_block, ResourceTable.Id_text_view))
                .include(TableBlock.class, TableEntry
                    .create(it -> it.tableLayout(ResourceTable.Layout_adapter_node_table_block, ResourceTable.Id_table_layout)
                        .textLayoutIsRoot(ResourceTable.Layout_view_table_entry_cell))).build();

        RecyclerView recyclerView = (RecyclerView) findComponentById(ResourceTable.Id_recycler_view);

        recyclerView.setAdapter(adapter);

       /* recyclerView.setHasFixedSize(true)
        recyclerView.itemAnimator = DefaultItemAnimator()
        recyclerView.adapter = adapter*/

        load(getApplicationContext(), data, new Result() {
            @Override
            public void onSuccess(String markdown) {
                Markwon markwonTemp = markwon;
                Node node = markwonTemp.parse(markdown);
                if (getWindow() != null) {
                    getUITaskDispatcher().syncDispatch(() -> {
                        adapter.setParsedMarkdown(markwon, node);
                        adapter.notify();
                        progressBar.setVisibility(Component.HIDE);
                    });
                }
            }

            @Override
            public void onFailure(Throwable e) {
                LogUtils.e("tag", e.getMessage());
            }
        });

    }

    interface Result {
        /**
         * result success
         * @param markdown String
         */
        void onSuccess(String markdown);
        /**
         * result Failure
         * @param e Throwable
         */
        void onFailure(Throwable e);
    }


    public static Intent makeIntent(Context context) {
        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withBundleName("io.noties.markwon.app")
                .withAbilityName("io.noties.markwon.app.readme.ReadMeActivity")
                .build();
        intent.setOperation(operation);
        return intent;
    }

    private void load(Context context, Uri data, Result mResult) {
        if (data == null) {
            mResult.onSuccess(SampleUtilsKt.loadReadMe(context));
        } else {
            Request request = new Request.Builder()
                    .get()
                    .url(ReadMeUtils.buildRawGithubUrl(data))
                    .build();
            new OkHttpClient().newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    mResult.onFailure(e);
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    mResult.onSuccess(response.body() != null ? response.body().string() : "");
                }
            });

        }
    }

    @Override
    public void onSaveAbilityState(PacMap outState) {
        super.onSaveAbilityState(outState);
    }
}
